<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import Cron from 'vue3-cron-antd';
import { useAntdForm, useFormRules } from '@/hooks/common/form';
import { createScheduleTask, fetchScheduleTaskClasses, updateScheduleTask } from '@/service/api/schedule-task';
import { fetchOnlineNodes } from '@/service/api/node';

const CronComponent = Cron;

defineOptions({
  name: 'ScheduleTaskOperateDrawer'
});

interface Props {
  /** 操作类型 */
  operateType: AntDesign.TableOperateType;
  /** 编辑行数据 */
  rowData?: any;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('open', {
  default: false
});

const { formRef, resetFields } = useAntdForm();
const { defaultRequiredRule } = useFormRules();

// 防止重复提交
const submitting = ref(false);
// 全局请求锁，防止多个组件同时请求
let globalRequestLock = false;
let buttonClickLock = false;
let submitTimestamp = 0;

const title = computed(() => {
  const titles: Record<AntDesign.TableOperateType, string> = {
    add: '新增定时任务',
    edit: '编辑定时任务'
  };
  return titles[props.operateType];
});

type Model = {
  taskName: string;
  description: string;
  cron: string;
  classMethod: string[]; // 使用数组存储 [className, methodName]
  nodeIp?: string;
  nodePort?: string;
  enabled: boolean; // 添加任务状态字段
};

const model = ref(createDefaultModel());

function createDefaultModel(): Model {
  return {
    taskName: '',
    description: '',
    cron: '',
    classMethod: [],
    nodeIp: '',
    nodePort: '',
    enabled: false // 默认停止状态
  };
}

type RuleKey = Extract<keyof Model, 'taskName' | 'description' | 'cron' | 'classMethod'>;

const rules: Record<RuleKey, App.Global.FormRule> = {
  taskName: defaultRequiredRule,
  description: defaultRequiredRule,
  cron: defaultRequiredRule,
  classMethod: defaultRequiredRule
};

/** 级联选择器数据源 */
const cascaderOptions = ref<any[]>([]);
/** 节点选项 */
const nodeOptions = ref<any[]>([]);

async function getCascaderOptions() {
  const { data, error: err } = await fetchScheduleTaskClasses();
  if (err) {
    console.error('Failed to load cascader options:', err);
    cascaderOptions.value = [];
    return;
  }

  const options: any[] = [];
  Object.entries(data || {}).forEach(([className, methods]) => {
    options.push({
      value: className,
      label: className,
      children: (methods as string[]).map(method => ({
        value: method,
        label: method
      }))
    });
  });

  cascaderOptions.value = options;
  console.log('Cascader options loaded:', options.length, 'classes');
}

async function getNodeOptions() {
  const { data, error: err } = await fetchOnlineNodes();
  if (err) {
    nodeOptions.value = [];
    return;
  }
  nodeOptions.value = data || [];
}

// 移除不需要的函数，级联选择器会自动处理

function handleInitModel() {
  model.value = createDefaultModel();

  if (props.operateType === 'edit' && props.rowData) {
    Object.assign(model.value, {
      taskName: props.rowData.taskName || '',
      description: props.rowData.description || '',
      cron: props.rowData.cron || '',
      classMethod:
        props.rowData.beanName && props.rowData.methodName ? [props.rowData.beanName, props.rowData.methodName] : [],
      nodeIp: props.rowData.nodeIp || '',
      nodePort: props.rowData.nodePort || '',
      enabled: props.rowData.enabled || false // 编辑时加载任务状态
    });
  }
}

function closeDrawer() {
  visible.value = false;
}

function validateForm(): string[] {
  const errors: string[] = [];
  if (!model.value.taskName?.trim()) errors.push('任务名称不能为空');
  if (!model.value.description?.trim()) errors.push('任务描述不能为空');
  if (!model.value.cron?.trim()) errors.push('Cron表达式不能为空');
  if (!model.value.classMethod || model.value.classMethod.length < 2) {
    errors.push('请选择执行类名和方法名');
  }
  if (!model.value.nodeIp?.trim()) {
    errors.push('节点IP不能为空');
  } else if (!model.value.nodeIp.includes(':')) {
    errors.push('节点IP格式不正确，请使用IP:端口格式');
  } else {
    const [ip, port] = model.value.nodeIp.split(':');
    if (!ip?.trim()) errors.push('节点IP不能为空');
    if (!port?.trim()) errors.push('节点端口不能为空');
  }
  return errors;
}

function prepareSubmitData() {
  // 确保nodeIp和nodePort不为空，validateForm已验证过格式
  const [ip, port] = model.value?.nodeIp?.split(':') || [];
  const nodeIp = ip.trim();
  const nodePort = port.trim();

  const [beanName, methodName] = model.value.classMethod || [];

  // 从全局状态获取当前用户作为创建者
  // 假设项目中有全局状态管理，例如使用pinia或vuex
  // 这里使用一个示例路径，实际项目中请替换为正确的获取方式
  const creator = ''; // 临时留空，实际应用中替换为: useUserStore()?.userInfo?.username || ''

  return {
    taskName: model.value.taskName.trim(),
    description: model.value.description.trim(),
    cron: model.value.cron.trim(),
    beanName,
    methodName,
    nodeIp,
    nodePort,
    enabled: model.value.enabled,
    creator
  };
}

// 重置提交状态的辅助函数
function resetSubmitState() {
  submitting.value = false;
  globalRequestLock = false;
  buttonClickLock = false;
}

async function handleSubmit() {
  const now = Date.now();
  // 防止重复提交
  if (now - submitTimestamp < 500 || submitting.value || globalRequestLock || buttonClickLock) {
    return;
  }

  submitting.value = true;
  globalRequestLock = true;
  buttonClickLock = true;
  submitTimestamp = now;

  try {
    // 表单验证
    const errors = validateForm();
    if (errors.length > 0) {
      window.$message?.error(errors.join('、'));
      return;
    }

    const submitData = prepareSubmitData();
    // 再次检查状态，确保没有被其他操作改变
    if (!submitting.value || !globalRequestLock) {
      return;
    }

    // 处理提交逻辑
    if (props.operateType === 'add') {
      const { error: err } = await createScheduleTask(submitData);
      if (!err) {
        window.$message?.success('新增定时任务成功');
        closeDrawer();
        emit('submitted');
      } else {
        window.$message?.error('新增定时任务失败');
      }
    } else {
      const { error: err } = await updateScheduleTask(props.rowData?.taskId, submitData);
      if (!err) {
        window.$message?.success('更新定时任务成功');
        closeDrawer();
        emit('submitted');
      } else {
        window.$message?.error('更新定时任务失败');
      }
    }
  } finally {
    // 无论成功失败，都重置状态
    resetSubmitState();
  }
}

watch(visible, () => {
  if (visible.value) {
    handleInitModel();
    resetFields();
    getCascaderOptions();
    getNodeOptions();
  }
});

// 移除不需要的监听器，级联选择器会自动处理
</script>

<template>
  <ADrawer v-model:open="visible" :title="title" :width="600">
    <AForm ref="formRef" layout="vertical" :model="model" :rules="rules">
      <AFormItem label="任务名称" name="taskName">
        <AInput v-model:value="model.taskName" placeholder="请输入任务名称" :maxlength="50" show-count />
      </AFormItem>

      <AFormItem label="任务描述" name="description">
        <ATextarea
          v-model:value="model.description"
          placeholder="请输入任务描述"
          :rows="3"
          :maxlength="200"
          show-count
        />
      </AFormItem>

      <AFormItem label="Cron表达式" name="cron">
        <AInput v-model:value="model.cron" placeholder="请输入Cron表达式" class="mb-8px" />
      </AFormItem>
      <div class="cron-helper">
        <div class="cron-desc">可视化选择 Cron 表达式，支持秒、分、时、日、月、周、年等配置</div>
        <CronComponent
          v-model:value="model.cron"
          :show-result="true"
          :show-result-text="true"
          i18n="cn"
          :hide-second="false"
          :hide-year="true"
          class="cron-wrapper"
        />
      </div>

      <AFormItem label="执行类名和方法名" name="classMethod">
        <ACascader
          v-model:value="model.classMethod"
          :options="cascaderOptions as any"
          placeholder="请选择执行类名和方法名"
          show-search
          :filter-option="
            (inputValue: string, path: any[]) => {
              return path.some((option: any) => option.label.toLowerCase().includes(inputValue.toLowerCase()));
            }
          "
          expand-trigger="hover"
        />
      </AFormItem>

      <AFormItem label="任务状态" name="enabled">
        <ASwitch v-model:checked="model.enabled" checked-children="启用" un-checked-children="禁用" />
      </AFormItem>

      <AFormItem label="目标节点">
        <ASelect v-model:value="model.nodeIp" placeholder="选择目标节点" allow-clear>
          <ASelectOption
            v-for="node in nodeOptions"
            :key="`${node.ip}:${node.port}`"
            :value="`${node.ip}:${node.port}`"
          >
            {{ `${node.ip}:${node.port}` }}
          </ASelectOption>
        </ASelect>
      </AFormItem>

      <!-- 按钮放在表单内部 -->
      <AFormItem>
        <ASpace :size="16">
          <AButton :disabled="submitting" @click="closeDrawer">取消</AButton>
          <AButton type="primary" :loading="submitting" :disabled="submitting" @click="handleSubmit">
            {{ submitting ? '提交中...' : '确认' }}
          </AButton>
        </ASpace>
      </AFormItem>
    </AForm>
  </ADrawer>
</template>

<style scoped>
.cron-helper {
  border: none;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
  margin-top: 8px;
}
.cron-helper > .cron-desc {
  color: #888;
  font-size: 13px;
  margin-bottom: 10px;
}
.cron-wrapper {
  width: 100% !important;
}
:deep(.ant-tabs-card) > .ant-tabs-nav .ant-tabs-tab {
  padding: 8px 30px !important;
  border-radius: 0px 0px 0 0;
}

/* 移除cron-tabs导航栏背景 */
:deep(.cron-tabs .ant-tabs-nav) {
  background: none !important;
}

/* 移除expression和preview区域内title的label背景 */
:deep(.cron-tabs .expression-title .ant-form-item-label) {
  background: none !important;
}

:deep(.cron-tabs .preview-title .ant-form-item-label) {
  background: none !important;
}
</style>
